﻿/* PictureBox.cpp
 * 
 * Copyright (C) 2020, 2021 Yuan LI
 * email:18069211@qq.com
 * https://blog.csdn.net/liyuanbhu
 * 
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 */

#include "PictureBox.h"
#include <QPainter>
#include <QDebug>
static const int IMAGE_WIDTH = 160;
static const int IMAGE_HEIGHT = 120;
static const QSize IMAGE_SIZE = QSize(IMAGE_WIDTH, IMAGE_HEIGHT);

#include <QMap>

QMap<QString, PictureBox *> Map;

int namedWindow(QString name, int flag)
{
    if (Map.contains(name))
    {
        PictureBox * p = Map[name];
        p->setMode((PictureBox::PB_MODE) flag);
        return 1;
    }
    else
    {
        PictureBox * p = new PictureBox((PictureBox::PB_MODE) flag, 0);
        p->setWindowTitle(name);
        Map[name] = p;
        p->show();
        return 1;
    }
    return 0;
}

int destroyWindow(QString name)
{
    if (Map.contains(name))
    {
        PictureBox * p = Map[name];
        delete p;
        Map.remove(name);
        return 1;
    }
    return 0;
}
int imshow(QString name, QImage &image)
{
    if (Map.contains(name))
    {
        PictureBox * p = Map[name];
        p->setImage(image, 1);
        p->show();
        return 1;
    }
    else
    {
        PictureBox * p = new PictureBox(PictureBox::AUTO_ZOOM, 0);
        p->setWindowTitle(name);
        Map[name] = p;
        p->setImage(image, 1);
        p->show();
        return 1;
    }
    return 0;
}

PictureBox::PictureBox(PB_MODE mode, QWidget *parent) : QWidget(parent)
{
    m_pixmap = QPixmap(IMAGE_SIZE);
    m_pixmap.fill();
    m_scale = 1.0;  
    m_brush = QBrush(Qt::white);
    setMode(mode);
}

void PictureBox::setBackground(QBrush brush)
{
    m_brush = brush;
    update();
}

void PictureBox::setMode(PB_MODE mode)
{
    if(m_mode == FIXED_SIZE && mode != FIXED_SIZE)
    {
        setMaximumSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
        setMinimumSize(10, 10);
    }
    m_mode = mode;
    if(m_mode == AUTO_SIZE)
    {
        setFixedSize(m_pixmap.size() * m_scale);
    }
    update();
}

bool PictureBox::setImage(QImage &image, double scale)
{
    if(image.isNull())
    {
        return false;
    }
    QPixmap p = QPixmap::fromImage(image);

    m_pixmap = p;
    m_scale = qBound(0.01, scale, 100.0);
    if(m_mode == AUTO_SIZE)
    {
        setFixedSize(m_pixmap.size() * m_scale);
    }
    update();
    return true;
}

void PictureBox::paintEvent(QPaintEvent * event)
{
    Q_UNUSED(event);
    QPainter painter(this);
    painter.setBackground(m_brush);
    painter.eraseRect(rect());

    double window_width, window_height;
    double image_width, image_height;
    double r1, r2, r;
    int offset_x, offset_y;
    switch (m_mode)
    {
    case FIXED_SIZE:
    case AUTO_SIZE:
        painter.scale(m_scale, m_scale);
        painter.drawPixmap(0, 0, m_pixmap);
        break;
    case FIX_SIZE_CENTRED:
        window_width = width();
        window_height = height();
        image_width = m_pixmap.width();
        image_height = m_pixmap.height();
        offset_x = (window_width - m_scale * image_width) / 2;
        offset_y = (window_height - m_scale * image_height) / 2;
        painter.translate(offset_x, offset_y);
        painter.scale(m_scale, m_scale);
        painter.drawPixmap(0, 0, m_pixmap);
        break;
    case AUTO_ZOOM:
        window_width = width();
        window_height = height();
        image_width = m_pixmap.width();
        image_height = m_pixmap.height();
        r1 = window_width / image_width;
        r2 = window_height / image_height;
        r = qMin(r1, r2);
        offset_x = (window_width - r * image_width) / 2;
        offset_y = (window_height - r * image_height) / 2;
        painter.translate(offset_x, offset_y);
        painter.scale(r, r);
        painter.drawPixmap(0, 0, m_pixmap);
        break;
    }
}

PictureBox::~PictureBox()
{

}

